package fileDistributionStatistics;


import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class AverageWeightedRedundancy {
	File fFile;
	
	final int startingFileSize =40*1024 ;
	int sumOfSmallFileSizes = 0;
	List<FileSizeInfo> fileInfo = new ArrayList<FileSizeInfo>();
	

	public AverageWeightedRedundancy(File aFileName) {
		fFile = aFileName;
	}

	public final void processLineByLine() throws FileNotFoundException {
		// Note that FileReader is used, not File, since File is not Closeable
		Scanner scanner = new Scanner(new FileReader(fFile));
		try {

			// first use a Scanner to get each line
			while (scanner.hasNextLine()) {
				processLine(scanner.nextLine());
			}
		} finally {
			scanner.close();
		}
	}

	protected void processLine(String aLine) {
		// use a second Scanner to parse the content of each line
		Scanner scanner = new Scanner(aLine);

		int rep1;
		scanner.useDelimiter(":");
		if (scanner.hasNext()) {
			String fs = scanner.next().trim();
			String rep = scanner.next().trim();
			rep1 = Integer.parseInt(rep);
			// rep1=1;
//			System.out.println(" " + fs + " " + rep1);
			fileInfo.add(new FileSizeInfo(Double.parseDouble(fs), Integer
					.parseInt(rep)));
		}
		scanner.close();
	}

	public void preProcessFileSize() {

		for (int i = 0; i < fileInfo.size(); i++) {
			double fs = fileInfo.get(i).fileSize;
			if (fs <= startingFileSize) {
				sumOfSmallFileSizes += (fs * fileInfo.get(i).numberOfFiles);
			}
		}
		int numberOf40KB = (int) Math.ceil((double) sumOfSmallFileSizes
				/ startingFileSize);
		int index = 0;
		for (int i = 0; i < fileInfo.size(); i++) {
			if (fileInfo.get(i).fileSize == startingFileSize) {
				index = i;
				break;
			}
		}
		System.out.println(" is starting source frag present" + index + " "
				+ sumOfSmallFileSizes + " " + numberOf40KB);
		if (index != 0) {
			int existingNumberOf40KB = fileInfo.get(index).numberOfFiles;
			System.out.println(" existing num " + existingNumberOf40KB);
			// FileSizeInfo temp = new FileSizeInfo((double)startingFileSize,
			// existingNumberOf40KB);
			// fileInfo.remove(index);
			fileInfo.get(index).setNumberOfFiles(
					existingNumberOf40KB + numberOf40KB);
			// fileInfo.add(new FileSizeInfo((double) startingFileSize,
			// existingNumberOf40KB+numberOf40KB));
		} else {
			fileInfo.add(new FileSizeInfo((double) startingFileSize,
					numberOf40KB));
		}

		System.out.println("done!!");
		int i = 0;
		while (fileInfo.size() != 0) {
			double fs = fileInfo.get(i).fileSize;
			if (fs < startingFileSize) {
				if (fs == startingFileSize)
					System.out.println(fs);
				fileInfo.remove(i);
				i = 0;
			} else {
				i++;
			}

			if (i == fileInfo.size()) {
				break;
			}
		}
		System.out.println("done removing!!");
		for (i = 0; i < fileInfo.size(); i++) {
			if (fileInfo.get(i).fileSize == startingFileSize) {
				System.out.println(" 40 kb source file"
						+ fileInfo.get(i).fileSize + "no of copies"
						+ fileInfo.get(i).numberOfFiles);
			}
		}

	}

	public void calculateFragmentSize() {
		
		FileSizeDistributionCalculation f = new FileSizeDistributionCalculation();
//	     int denominator=0;
	     double[] redundancy= new double[fileInfo.size()];
	     double[] weightes = new double[fileInfo.size()];
	     double[] wt_temp= new double[fileInfo.size()];
	     double weightNum=0;
	     double weightedDeno = 0;
	     double averageWeightedR=0;
	     double sumOfSourceFile=0;
	     int num=0;
	     System.out.println(" in frag size method");
		for (int i = 0; i < fileInfo.size(); i++) {
			double source_file = fileInfo.get(i).fileSize;
			int rep = fileInfo.get(i).numberOfFiles;
			f.numberOfSourceFragments = 128;
			f.setNumberOfSourceFragments(f.numberOfSourceFragments);
			f.sourceFileLength = (double) Math.abs(source_file);
			f.setSourceFileLength(f.sourceFileLength);
			
			f.fragmentSize = f.calculateFragmentSize();
//			System.out.println(f.fragmentSize);
			double totalEncodedSpaceOccupied = f.setParameters();
			double factor = f.getSourceFileLength() % 4096;
			double sourceFileDiskSpaceOccupied = f.getSourceFileLength();
			if (factor != 0) {
				sourceFileDiskSpaceOccupied = f.getSourceFileLength()
						+ (4096 - factor);
			} 
			
//				System.out.println(f.sourceFileLength);
//				System.out.println(f.fragmentSize);
				redundancy[i]=totalEncodedSpaceOccupied/sourceFileDiskSpaceOccupied;
//				System.out.println(redundancy[i]);
				num++;
		
//			weightedR+=redundancy[i];
//			System.out.println(redundancy[i]);
			wt_temp[i]=source_file*rep;
			sumOfSourceFile+=(source_file*rep);
		}
		System.out.println(sumOfSourceFile);
		for ( int i=0;i<fileInfo.size();i++){
//			System.out.println(wt[i]/sumOfSourceFile);
			weightes[i]=wt_temp[i]/sumOfSourceFile;
			weightedDeno+=weightes[i];
		}
		System.out.println(weightedDeno);
		
		for( int i=0;i<fileInfo.size();i++){
			weightNum+=(weightes[i]*redundancy[i]);
		}
		averageWeightedR=weightNum/weightedDeno;
		
		System.out.println(averageWeightedR);
		
//		averageWeightedR=weightedR/num;
//		System.out.println(" weighted R"+averageWeightedR);
	}

	public static void main(String[] args) {
		File parseFilename = new File("C:" + File.separator + "Users"
				+ File.separator + "Bhavya" + File.separator + "Desktop"
				+ File.separator + "Cloud_Computing_FYP" + File.separator
				+ "FileSizeDistributionStatistics" + File.separator
				+ "CalculatedfileSizeGreatertan1byte.txt");
    
		AverageWeightedRedundancy parser = new AverageWeightedRedundancy(parseFilename);
		try {
			parser.processLineByLine();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		parser.preProcessFileSize();
		parser.calculateFragmentSize();
		// System.out.println("done");
//		System.out.println("weighted R");
	}
}
